' Copyright 2011-2012 Martin Leidel
'
' This software is provided 'as-is', without any express or implied
' warranty.  In no event will the authors be held liable for any damages
' arising from the use of this software.
' 
' Permission is granted to anyone to use this software for any purpose,
' including commercial applications, and to alter it and redistribute it
' freely, subject to the following restrictions:
' 
' 1. The origin of this software must not be misrepresented; you must not
' claim that you wrote the original software. If you use this software
' in a product, an acknowledgment in the product documentation would be
' appreciated but is not required.
' 2. Altered source versions must be plainly marked as such, and must not be
' misrepresented as being the original software.
' 3. This notice may not be removed or altered from any source distribution.

Strict

Import mojo
Import mnet

Global isServer:Bool = True

Function Main:Int()
  New TestApp()
  Return 0
End Function

Class TestApp Extends App
  Field result:Int
  Field sResult:Int
  Field socket:Socket = Null
  Field msg:String
  Field recvMsg:String
  Field sendMsg:Bool = False
  Field clients:List< Int >
  Field messages:IntMap< String >

  Method OnCreate:Int()
    SetUpdateRate(30)
    
    EnableKeyboard()
    
    socket = New Socket()
    result = socket.Init()
    If( isServer )
      sResult = socket.CreateServer( 12345 )
      clients = New List< Int >
      messages = New IntMap< String >
    Else
      sResult = socket.ConnectToServer( "localhost", 12345 )
    End If
    Return 0
  End Method

  Method OnUpdate:Int()
    Repeat
      Local char:Int = GetChar()
      If( Not char ) Then Exit

      If( char >= 32 )
        msg += String.FromChar( char )
      Else
        Select char
          Case 8
            msg = msg[..-1]
          Case 13
            sendMsg = True
            Exit
          Case 27
            msg = ""
        End Select
      End If
    Forever
    
    If( KeyHit( KEY_ESCAPE ) )
      socket.Close()
      Error ""
    End If
    
    If( isServer )
      socket.UpdateServer()
      If( socket.HasNewClientConnected() > 0 )
        clients.AddLast( socket.GetLastClient() )
      End If
      'Iterate through all clients and check if they are still there
      For Local c:Int = EachIn clients
        If( Not socket.IsClientConnected( c ) )
          clients.Remove( c )
        End If
      Next
    End If
    
    If( sendMsg )
      sendMsg = False
      socket.SendBroadcast( msg )
      msg = ""
    End If
    
    Return 0
  End Method
  
  Method OnSuspend:Int()
    Return 0
  End Method
  
  Method OnResume:Int()
    Return 0
  End Method

  Method OnRender:Int()
    Cls
    DrawText( "Result: " + result, 10, 10 )
    DrawText( "sResult: " + sResult, 10, 30 )
    If( isServer )
      DrawText( "Number of clients: " + socket.GetNumberOfClients(), 10, 50 )
      DrawText( "Last client id: " + socket.GetLastClient(), 10, 70 )
      DrawText( "Client id: " + socket.GetLastClient() + " connected: " + socket.IsClientConnected( socket.GetLastClient() ), 10, 90 )
      Local i:Int = 110
      For Local c:Int = EachIn clients
        Local msg:String = socket.ReceiveFromClient( c )
        If( msg <> "" ) Then messages.Insert( c, msg )
        DrawText( "Msg from client id: " + c + messages.Get( c ), 10, i )
        i += 10
      Next
    Else
      DrawText( "Connected: " + socket.IsConnected(), 10, 50 )
      Local rmsg:String = socket.Receive()
      If( rmsg <> "" ) Then recvMsg = rmsg
      DrawText( "Msg from server: " + recvMsg, 10, 70 )
    End If
    
    DrawText( "Enter text: " + msg, 10, 460 )
    Return 0
  End Method

End Class
